#include "graph.h"

int draw_gen_graph(tree_node_t *node, int m) {
	int n = 0;
	int tmp = m+1;

	if(LEFT_CHILD(node) != NULL) {
		n = draw_gen_graph(LEFT_CHILD(node), tmp);
		draw_gen_graph_out(" %d -> %d\n", m, tmp);
	}
	if(RIGHT_CHILD(node) != NULL) {
		tmp = m+n+1;
		n += draw_gen_graph(RIGHT_CHILD(node), tmp);
		draw_gen_graph_out(" %d -> %d\n", m, tmp);
	}

	switch(node->op_type) {
		case NONE:
			draw_gen_graph_out("%d[ label = \"%s\" ]\n", m, node->name);
			break;
		case OP_ADD:
			draw_gen_graph_out("%d[ label = \"+\" ]\n", m);
			break;
		case OP_MUL:
			draw_gen_graph_out("%d[ label = \"*\" ]\n", m);
			break;
		case OP_UN_NEG:
			draw_gen_graph_out("%d[ label = \"-\" ]\n", m);
			break;
		case OP_ARR:
			draw_gen_graph_out("%d[ label = \"ID + []\" ]\n", m);
			break;
		case OP_NEQ:
			draw_gen_graph_out("%d[ label = \"!=\" ]\n", m);
			break;
		case OP_LESS:
			draw_gen_graph_out("%d[ label = \">\" ]\n", m);
			break;
		case OP_CALL:
			draw_gen_graph_out("%d[ label = \"CALL(...)\" ]\n", m);
			break;
		case OP_CALL_VOID:
			draw_gen_graph_out("%d[ label = \"CALL()\" ]\n", m);
			break;
		case OP_ARG:
			draw_gen_graph_out("%d[ label = \"ARG\" ]\n", m);
			break;
		case OP_ARG_NIL:
			draw_gen_graph_out("%d[ label = \"ARG_NIL\" ]\n", m);
			break;
		case TERM_ID:
			draw_gen_graph_out("%d[ label = \"%s\" ]\n", m, node->data.child[0]->data.id.name);
			break;
		case TERM_CONST:
			draw_gen_graph_out("%d[ label = \"%ld\" ]\n", m, node->data.child[0]->data.num.val);
			break;
		case OPL_AND:
			draw_gen_graph_out("%d[ label = \"AND\" ]\n", m);
			break;
		case OPL_NOT:
			draw_gen_graph_out("%d[ label = \"NOT\" ]\n", m);
			break;
		default:
			draw_gen_graph_out("# Encountered unkonwn node type\n");
			break;
	}
	return 1+n;
}

int draw_graph(tree_node_t *node, int m) {
	int n = 0;
	switch(node->type) {
		case NONTERMINAL:
			for(int i=0; i<MC; i++) {
				if((node->data.child)[i] != NULL) {
					int tmp = m+n+1;
					n += draw_graph((node->data.child)[i], tmp);
					draw_graph_out(" %d -> %d\n", m, tmp);
				}
			}
			draw_graph_out("%d[ label = \"%s\" ]\n", m, node->name);
			break;
		case TERMINAL_ID:
			draw_graph_out("%d[ label = \"%s\" ]\n", m, node->data.id.name);
			break;
		case TERMINAL_NUM:
			draw_graph_out("%d[ label = \"%ld\" ]\n", m, node->data.num.val);
			break;
		case TERMINAL_TOK:
			draw_graph_out("%d[ label = \"", m);
			switch(node->data.token) {
				case END:
					draw_graph_out("END");
					break;
				case RETURN:
					draw_graph_out("RETURN");
					break;
				case GOTO:
					draw_graph_out("GOTO");
					break;
				case IF:
					draw_graph_out("IF");
					break;
				case VAR:
					draw_graph_out("VAR");
					break;
				case AND:
					draw_graph_out("AND");
					break;
				case NOT:
					draw_graph_out("NOT");
					break;
				case NEQ:
					draw_graph_out("NEQ");
					break;
				default: ;
			}
			draw_graph_out("\" ]\n");
			break;
		case TERMINAL_LEX:
			draw_graph_out("%d[ label = \"%c\" ]\n", m, node->data.lexem);
			break;
		default:
			break;
	}
	return 1+n;
}
